#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdarg.h>
#include "public.h"

/* VARARGS */
void error(const char *fmt, ...)
{
    va_list ap;

    (void)fprintf(stderr, "%s: ", g_program_name);
    va_start(ap, fmt);
    (void)vfprintf(stderr, fmt, ap);
    va_end(ap);
    if (*fmt) {
        fmt += strlen(fmt);
        if (fmt[-1] != '\n')
            (void)fputc('\n', stderr);
    }
    exit(1);
    /* NOTREACHED */
}


/*
 * Copy arg vector into a new buffer, concatenating arguments with spaces.
 */
char *copy_argv(register char **argv)
{
    register char **p;
    register uint32_t len = 0;
    char *buf;
    char *src, *dst;

    p = argv;
    if (*p == 0)
        return 0;

    while (*p)
        len += strlen(*p++) + 1;

    buf = (char *)malloc(len);
    if (buf == NULL)
        error("copy_argv: malloc");

    p = argv;
    dst = buf;
    while ((src = *p++) != NULL) {
        while ((*dst++ = *src++) != '\0')
            ;
        dst[-1] = ' ';
    }
    dst[-1] = '\0';

    return buf;
}
/*
 * Convert a token value to a string; use "fmt" if not found.
 */
const char *
tok2strbuf(register const struct tok *lp, register const char *fmt,
       register u_int v, char *buf, size_t bufsize)
{
    if (lp != NULL) {
        while (lp->s != NULL) {
            if (lp->v == v)
                return (lp->s);
            ++lp;
        }
    }
    if (fmt == NULL)
        fmt = "#%d";

    (void)snprintf(buf, bufsize, fmt, v);
    return (const char *)buf;
}

/*
 * Convert a token value to a string; use "fmt" if not found.
 */
const char *
tok2str(register const struct tok *lp, register const char *fmt,
    register u_int v)
{
    static char buf[4][128];
    static int idx = 0;
    char *ret;

    ret = buf[idx];
    idx = (idx+1) & 3;
    return tok2strbuf(lp, fmt, v, ret, sizeof(buf[0]));
}

